#include <iostream>
#include <fstream>
#include <sstream>

#include "adatbazis.h"
#include "oszlop.h"
#include "funktor.h"

std::vector<std::string> Vec_from_string(const std::string& string)
{
	std::vector<std::string> v;
	
	std::stringstream ss(string);
	std::string s;
	
	while (std::getline(ss, s, ';'))
	{
		v.push_back(s);
	}
	
	return v;
}

void Open_from_file(Adatbazis& adatb, const std::string& s)
{	
	std::ifstream f(s.c_str());
	std::string sor;
	std::getline(f, sor);
	
	std::vector<std::string> tablak = Vec_from_string(sor);
	
	for (int i = 0; i < tablak.size(); ++i)
	{	
		std::fstream t(tablak[i].c_str());
		
		std::getline(t, sor);
		
		adatb.Letrehoz("");
		
		std::vector<std::string> oszlopok = Vec_from_string(sor);

		for (int j = 0; j < oszlopok.size(); ++j)
		{
			if (oszlopok[j][0] == 'L')
			{
				Oszlop_log* a = new Oszlop_log(oszlopok[j].erase(0,1));
				adatb._tablak[i]->_oszlopok.push_back(a);
			}
			else if (oszlopok[j][0] == 'E')
			{
				Oszlop_egesz* a = new Oszlop_egesz(oszlopok[j].erase(0,1));
				adatb._tablak[i]->_oszlopok.push_back(a);
			}
			else if (oszlopok[j][0] == 'V')
			{
				Oszlop_valos* a = new Oszlop_valos(oszlopok[j].erase(0,1));
				adatb._tablak[i]->_oszlopok.push_back(a);
			}
			else if (oszlopok[j][0] == 'S')
			{
				Oszlop_szoveg* a = new Oszlop_szoveg(oszlopok[j].erase(0,1));
				adatb._tablak[i]->_oszlopok.push_back(a);
			}
			
			++adatb._tablak[i]->_oszlopok_szama;
		}
		
		while (t.good())
		{
			std::getline(t, sor);
			if (t.fail()) break;
			
			std::vector<std::string> ertekek = Vec_from_string(sor);
			for (int k = 0; k < ertekek.size(); ++k)
			{
				adatb._tablak[i]->_oszlopok[k]->Feltolt(ertekek[k]);
			}
			adatb._tablak[i]->_sorok_szama++;
		}
		
		t.close();
		
		adatb._tablak[i]->_nev = tablak[i];
	}	
	
	f.close();
}

class Menu
{
	Adatbazis* adatbp;
	std::string tabla;
	int tablai;
	
	void Uj();
	void MenuWrite();
	void MenuWriteT();
	void AbLetrehoz();
	void AbMegnyit();
	void AbTorol();
	void AbLekerdezes();
	
	void TModositFelvetel();
	void TBeszur();
	void TListaz();
	void TSzurtListaz();
	void Torol();
	void TUrit();
public:
	void Run();
	void RunT();
	~Menu() { delete adatbp; }
};

int main()
{
	Menu m;
	m.Run();
	
	return 0;
}

void Menu::Run()
{
	int c = 0;
	MenuWrite();
	do
	{
		std::cin >> c;
		switch(c)
		{
			case 1 : Menu::Uj(); break;
			case 2 : Menu::AbMegnyit(); break;
			case 3 : Menu::AbLekerdezes(); break;
			case 4 : Menu::AbLetrehoz(); break;
			case 5 : Menu::AbTorol(); break;
			case 6 : Menu::RunT(); break;
		}
	}while(c != 0);
}

void Menu::RunT()
{
	int c = 0;
	MenuWriteT();
	do
	{
		std::cin >> c;
		switch(c)
		{
			case 1 : Menu::TModositFelvetel(); break;
			case 2 : Menu::TBeszur(); break;
			case 3 : Menu::TListaz(); break;
			case 4 : Menu::TSzurtListaz(); break;
			case 5 : Menu::Torol(); break;
			case 6 : Menu::TUrit(); break;
			case 7 : Menu::Run(); break;
		}
	}while(c != 0);
}

void Menu::MenuWrite()
{
	std::cout << std::endl;
	std::cout << "(1) Uj adatbazis letrehozasa " << std::endl;
	std::cout << "(2) Adatbazis megnyitasa fajlbol " << std::endl;
	std::cout << "(3) Adatbazis tablainak lekerdezese " << std::endl;
	std::cout << "(4) Tabla hozzavetele " << std::endl;
	std::cout << "(5) Adatbazis egy tablajanak torlese " << std::endl;
	std::cout << "(6) Tablamuveletek " << std::endl;
	std::cout << "(0) Kilepes " << std::endl;
}

void Menu::MenuWriteT()
{
	std::cout << "A tablak: " << adatbp->Lekerdezes() << std::endl;
	std::cout << "Hanyadik tabla: ";
	std::cin >> tablai;
	tablai = tablai - 1;
	
	std::cout << std::endl;
	std::cout << "(1) Uj oszlop hozzavetele a tablahoz " << std::endl;
	std::cout << "(2) Uj sor beszurasa a tablaba " << std::endl;
	std::cout << "(3) Tabla tartalmanak listazasa " << std::endl;            
	std::cout << "(4) Tabla tartalmanak listazasa feltetel szerint " << std::endl;
	std::cout << "(5) Tabla tartalmanak torlese feltetel szerint " << std::endl;
	std::cout << "(6) Tabla uritese " << std::endl;
	std::cout << "(7) Vissza az adatbazis menube " << std::endl;
	std::cout << "(0) Kilepes " << std::endl;
}

void Menu::Uj()
{
	std::string s;
	std::cout << "Adatbazis neve: ";
	std::cin >> s;
	adatbp = new Adatbazis(s);
}

void Menu::AbLetrehoz()
{
	std::string s;
	std::cout << "Tabla neve: ";
	std::cin >> s;
	adatbp->Letrehoz(s);
}

void Menu::AbMegnyit()
{
	std::string s;
	std::cout << "Fajl neve: ";
	std::cin >> s;
	Adatbazis* adatb = new Adatbazis("");
	Open_from_file(*adatb, s);
	adatb->_nev = s;
	adatbp = adatb;
}

void Menu::AbTorol()
{
	std::cout << "A tablak: " << adatbp->Lekerdezes() << std::endl;
	std::cout << "Torlendo tabla neve: ";
	std::string s;
	std::cin >> s;
	adatbp->Torol(s);
}

void Menu::AbLekerdezes()
{
	std::cout << adatbp->Lekerdezes() << std::endl;
}
	
void Menu::TModositFelvetel()
{
	std::string nev, tipus;
	std::cout << "Nev: ";
	std::cin >> nev;
	std::cout << "Tipus: ";
	std::cin >> tipus;
	
	if (adatbp->_tablak[tablai]->_sorok_szama == 0) adatbp->_tablak[tablai]->Modosit_felvetel(nev, tipus);
	else
	{
		std::string ertekek;
		std::cout << "ertekek: ";
		std::cin >> ertekek;
		adatbp->_tablak[tablai]->Modosit_felvetel(nev, tipus, ertekek);
	}
}

void Menu::TBeszur()
{
	std::cout << "A sorban az ertekeket ;vel elvalasztva add meg! : ";
	std::string s;
	std::cin >> s;
	adatbp->_tablak[tablai]->Beszur(s);
}

void Menu::TListaz()
{
	std::cout << adatbp->_tablak[tablai]->Listaz() << std::endl;
}

void Menu::TSzurtListaz()
{
	std::cout << "Hanyadik oszlopra szurjunk: ";
	int n;
	std::cin >> n;
	n = n -1;
	std::string f1, f2;
	std::cout << "Mire szurjunk: ";
	std::cin >> f1;
	std::cout << "Relacio (kisebb,nagyobb,egyenlo) : ";
	std::cin >> f2;
	
	Funktor f(f1,f2);
	
	adatbp->_tablak[tablai]->Szurt_listaz(f, n);
}

void Menu::Torol()
{
	std::cout << "Hanyadik oszlopra szurjunk: ";
	int n;
	std::cin >> n;
	n = n -1;
	std::string f1, f2;
	std::cout << "Mire szurjunk: ";
	std::cin >> f1;
	std::cout << "Relacio (kisebb,nagyobb,egyenlo) : ";
	std::cin >> f2;
	
	Funktor f(f2,f1);
	
	adatbp->_tablak[tablai]->Torol(f, n);
}

void Menu::TUrit()
{
	adatbp->_tablak[tablai]->Urit();
}